package cn.lili.controller.payment;

import cn.lili.common.enums.DictCodeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.SysDictUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.vo.GradeVO;
import cn.lili.modules.member.service.GradeService;
import cn.lili.modules.order.order.entity.vo.OrderVO;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.payment.kit.CashierSupport;
import cn.lili.modules.payment.kit.dto.PayParam;
import cn.lili.modules.payment.entity.enums.PaymentClientEnum;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.payment.kit.params.dto.CashierParam;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.whitebar.entity.dos.RateSetting;
import cn.lili.modules.whitebar.entity.vo.RateSettingVO;
import cn.lili.modules.whitebar.mapper.RateSettingMapper;
import cn.lili.modules.whitebar.service.RateSettingService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 买家端,收银台接口
 *
 * @author Chopper
 * @since 2020-12-18 16:59
 */
@Slf4j
@RestController
@Api(tags = "买家端,收银台接口")
@RequestMapping("/buyer/cashier")
public class CashierController {

	@Autowired
	private CashierSupport cashierSupport;

	// 费率
	@Autowired
	private RateSettingService rateSettingService;

	@Autowired
	private GradeService gradeService;

	@Autowired
	private OrderService orderService;
	@Autowired
	private StoreService storeService;
	@Autowired
	private SettingService settingService;

	@ApiImplicitParams({
			@ApiImplicitParam(name = "client", value = "客户端类型", paramType = "path", allowableValues = "PC,H5,WECHAT_MP,APP")})
	@RequestMapping(value = "/tradeDetail")
	@ApiOperation(value = "获取支付详情")
	public ResultMessage paymentParams(@Validated PayParam payParam) {
		CashierParam cashierParam = cashierSupport.cashierParam(payParam);
		return ResultUtil.data(cashierParam);
	}

	@RequestMapping(value = "/tradeNativeDetail")
	@ApiOperation(value = "获取支付详情(扫码)")
	public ResultMessage paymentNative(@Validated PayParam payParam) {
		CashierParam cashierParam = cashierSupport.cashierParamsNative(payParam);
		return ResultUtil.data(cashierParam);
	}

	@RequestMapping(value = "/rateSetting")
	@ApiOperation(value = "获取合伙人费率")
	public ResultMessage findByPartner() {
		QueryWrapper<RateSetting> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("role_name", "推广员", "天使合伙人", "事业合伙人");
		List<RateSetting> list = rateSettingService.list(queryWrapper);
		return ResultUtil.data(list);
	}

	@RequestMapping(value = "/fee")
	@ApiOperation(value = "获取合伙人费率")
	public ResultMessage findByFee(String sn) {
		Double commission = 0D;
		if (StringUtils.isNotEmpty(sn)) {
			OrderVO bySn = orderService.getBySn(sn);
			Store store = storeService.getById(bySn.getStoreId());
			Double fee = Double.parseDouble(SysDictUtils.getValueString(DictCodeEnum.ORDER_FEE.dictCode()));
			if (store != null && "OPEN".equals(store.getStoreDisable()) && fee != null && fee.compareTo(0D) > 0) {
				commission = fee;
			} else if (store != null && "OPEN".equals(store.getStoreDisable())) {
				Setting setting = settingService.get(SettingEnum.ORDER_SETTING.toString());
				Gson gson = new Gson();
				Map map = new HashMap();
				map = gson.fromJson(setting.getSettingValue(), map.getClass());
				commission = CurrencyUtil.div(Double.parseDouble(map.get("b2bFee").toString()), 100);
			}
		} else {
			Setting setting = settingService.get(SettingEnum.ORDER_SETTING.toString());
			Gson gson = new Gson();
			Map map = new HashMap();
			map = gson.fromJson(setting.getSettingValue(), map.getClass());
			commission = CurrencyUtil.div(Double.parseDouble(map.get("b2bFee").toString()), 100);
		}
		return ResultUtil.data(commission);
	}

	@RequestMapping(value = "/grade")
	@ApiOperation(value = "获取会员充值费率")
	public ResultMessage findByGradeVO() {
		// 获取当前登录的会员
		AuthUser authUser = UserContext.getCurrentUser();
		if (authUser == null) {
			throw new ServiceException(ResultCode.USER_AUTH_EXPIRED);
		}
		// RateSettingVO rateSettingVO =
		// rateSettingService.findByPartner(authUser.getId());
		GradeVO gradeVO = gradeService.findByGradeVO(authUser.getId());
		return ResultUtil.data(gradeVO.getRechargeRule());
	}

	@ApiImplicitParams({
			@ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"),
			@ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP"),
			@ApiImplicitParam(name = "paymentPassword", value = "支付密码", required = true, paramType = "query")})
	@RequestMapping(value = "/pay/{paymentMethod}/{paymentClient}")
	@ApiOperation(value = "支付")
	public ResultMessage payment(@RequestHeader String uuid, HttpServletRequest request, HttpServletResponse response,
			@PathVariable String paymentMethod, @PathVariable String paymentClient,
			@RequestParam("paymentPassword") String paymentPassword, @Validated PayParam payParam) {
		PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);
		PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(paymentClient);
		payParam.setUuid(uuid);
		try {
			return cashierSupport.buyerPayment(paymentMethodEnum, paymentClientEnum, request, response, payParam,
					paymentPassword);
		} catch (ServiceException se) {
			log.info("支付异常", se);
			throw se;
		} catch (Exception e) {
			log.error("收银台支付错误", e);
		}
		return null;

	}

	@ApiOperation(value = "支付回调")
	@RequestMapping(value = "/callback/{paymentMethod}", method = {RequestMethod.GET, RequestMethod.POST})
	public ResultMessage<Object> callback(HttpServletRequest request, @PathVariable String paymentMethod) {

		PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);

		cashierSupport.callback(paymentMethodEnum, request);

		return ResultUtil.success(ResultCode.PAY_SUCCESS);
	}

	@ApiOperation(value = "支付异步通知")
	@RequestMapping(value = "/notify/{paymentMethod}", method = {RequestMethod.GET, RequestMethod.POST})
	public void notify(HttpServletRequest request, @PathVariable String paymentMethod) {

		PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(paymentMethod);

		cashierSupport.notify(paymentMethodEnum, request);

	}

	@ApiOperation(value = "查询支付结果")
	@RequestMapping(value = "/result")
	public ResultMessage<Boolean> paymentResult(PayParam payParam) {
		return ResultUtil.data(cashierSupport.paymentResult(payParam));
	}
}
